//
// World class - stores the structure of the real world (the cave)
// 
package classes;

import java.util.Random;

public class World {

	public char[][][] wumpusWorld;
	public char[][][] percepts;	
	private int worldSize;
	public static Random randomGenerator = new Random();
	
	public World(int size, char[][][] world){
		
			worldSize = size;
			
			wumpusWorld = new char[worldSize][worldSize][6];
			percepts = new char[worldSize][worldSize][4];

			// store world definition
			for (int i = 0; i < worldSize; i++) {
				for (int j = 0; j < worldSize; j++) {
					for (int k = 0; k < 6; k++) {
						wumpusWorld[i][j][k] = world[i][j][k];	
					}
				}
			}
			
			// initialize percept map
			for (int i = 0; i < worldSize; i++) {
				for (int j = 0; j < worldSize; j++) {
					for (int k = 0; k < 3; k++) {
						percepts[i][j][k] = ' ';
					}
				}
			}	
	}
	
	public int sizeOfWorld() {
		return worldSize;	
	}
	
	public Point getAgentLocation() {

		Point point = null;
		for (int i = 0; i < worldSize; i++) {
			for (int j = 0; j < worldSize; j++) {
				if (wumpusWorld[i][j][3] != ' ') {
					point = new Point(i,j);
				}
			}
		}	
		return point;
	}
	
	public void moveAgentToLocation(Point point) {
	  Point agent = getAgentLocation();
		wumpusWorld[agent.getX()][agent.getY()][3] = ' ';
	  wumpusWorld[point.getX()][point.getY()][3] = 'A';
	}
	
	public Point batsMooving() {
		int xAfterBat = 0;
		int yAfterBat = 0;
		boolean searchingPlace = true;
		while (searchingPlace) {
			xAfterBat = randomGenerator.nextInt(worldSize);
			yAfterBat = randomGenerator.nextInt(worldSize);
			int k;
			for (k = 0; k < 6; k++)
				if (wumpusWorld[xAfterBat][yAfterBat][k] != ' ') 
				  break;
      if (k==6) searchingPlace = false;
		}
		Point point = new Point(xAfterBat, yAfterBat);
		return point;
	}
	
	public void grabGold(int x, int y) {
		wumpusWorld[x][y][2] = ' ';
	}
	
	public void setPerceptMap() {
		
		// World: Pit, Wumpus, Gold, Agent, Bat, Exit
		// Needed: Pit, Wumpus, Gold
		// Percepts: Breeze,Stench,Glitter
		
		for (int i = 0; i < worldSize; i++) {
			for (int j = 0; j < worldSize; j++) {

				for (int k = 0; k < 4; k++) {
										
					if (wumpusWorld[i][j][k] == 'P') {
						
						if (j - 1 >= 0) {
							percepts[i][j - 1][k] = 'B';
						}
						else {
							percepts[i][j - 1 + worldSize][k] = 'B';
						}
									
						if (i + 1 < worldSize) {
							percepts[i + 1][j][k] = 'B';
						}
						else {
							percepts[i + 1 - worldSize][j][k] = 'B';
						}
						
						if (j + 1 < worldSize) {
							percepts[i][j + 1][k] = 'B';
						}
						else {
							percepts[i][j + 1 - worldSize][k] = 'B';
						}
						
						if (i - 1 >= 0) {
							percepts[i - 1][j][k] = 'B';
						}
						else {
							percepts[i - 1 + worldSize][j][k] = 'B';
						}
					}
					else if (wumpusWorld[i][j][k] == 'W') {
						if (j - 1 >= 0) {
							percepts[i][j-1][k] = 'S';
						}
						else {
							percepts[i][j - 1 + worldSize][k] = 'S';
						}
						
						if (i + 1 < worldSize) {
							percepts[i + 1][j][k] = 'S';
						}
						else {
							percepts[i + 1 - worldSize][j][k] = 'S';
						} 
						
						if (j + 1 < worldSize) {
							percepts[i][j + 1][k] = 'S';
						} else {
							percepts[i][j + 1 - worldSize][k] = 'S';
						}
						
						if (i - 1 >= 0) {
							percepts[i - 1][j][k] = 'S';
						} else {
							percepts[i - 1 + worldSize][j][k] = 'S';
						}
					}
					else if (wumpusWorld[i][j][k] == 'G') {
						if (j - 1 >= 0) {
							percepts[i][j-1][k] = 'G';
						}
						else {
							percepts[i][j - 1 + worldSize][k] = 'G';
						}
						
						if (i + 1 < worldSize) {
							percepts[i + 1][j][k] = 'G';
						}
						else {
							percepts[i + 1 - worldSize][j][k] = 'G';
						} 
						
						if (j + 1 < worldSize) {
							percepts[i][j + 1][k] = 'G';
						} else {
							percepts[i][j + 1 - worldSize][k] = 'G';
						}
						
						if (i - 1 >= 0) {
							percepts[i - 1][j][k] = 'G';
						} else {
							percepts[i - 1 + worldSize][j][k] = 'G';
						}
					}
					
				}
			}
		}	
	}
	
  private Point [] arrayOfPointsAround(int xLocation, int yLocation) {
    Point [] pointsAround = new Point [4];
    
    pointsAround[0] = new Point(xLocation,(yLocation+1)%worldSize); 
    pointsAround[1] = new Point((xLocation+1)%worldSize,yLocation);
    pointsAround[2] = new Point(xLocation,((yLocation-1)%worldSize+worldSize)%worldSize);
    pointsAround[3] = new Point(((xLocation-1)%worldSize+worldSize)%worldSize,yLocation);
    
    return pointsAround;
  }
   
  //want to know how many breeze, stench and glitter we have
  // need to look through 8 cells around
  public int[] getPercepts() {
    int numberOfBreeze = 0;
    int numberOfStench = 0;
    int numberOfGlitter = 0;
    
    Point agent = getAgentLocation();
    Point [] cellsAround = arrayOfPointsAround(agent.getX(),agent.getY());
    
    for(int i = 0; i < cellsAround.length; i++) {

        if (wumpusWorld[cellsAround[i].getX()][cellsAround[i].getY()][0] == 'P') {
          numberOfBreeze ++;
        }
        if (wumpusWorld[cellsAround[i].getX()][cellsAround[i].getY()][1] == 'W') {
          numberOfStench ++;
        }
        if (wumpusWorld[cellsAround[i].getX()][cellsAround[i].getY()][2] == 'G') {
          numberOfGlitter ++;
        }
    }
    
    int [] perceptsArray = new int[3];
    perceptsArray[0] = numberOfBreeze;
    perceptsArray[1] = numberOfStench;
    perceptsArray[2] = numberOfGlitter;
    return perceptsArray;
  
  }

  public char [] getObjects() {
    Point p = getAgentLocation();
    return wumpusWorld[p.getX()][p.getY()];
  }

	public void printWorld() {
	  for (int j=worldSize-1; j>=0; j--) {
	    for (int i=0; i<worldSize; i++) {
	      char out=' ';
	      for (int k=0; k<6; k++)
	        if (wumpusWorld[i][j][(k+3)%6]!=' ') {
	          out=wumpusWorld[i][j][(k+3)%6];
	          break;
	        }
	      if (out=='P' && wumpusWorld[i][j][1]=='W') out='U';
	      System.out.print("|" + out);
	    }
	    System.out.println("|");
	  }
	}
	
}
